#include "include/thread.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "include/common.h"
#include "include/command.h"
#include "include/LogSystem.h"
#include "include/stack.h"
#define BUF_SIZE 1024

int taskEnqueue(taskQueue_t *pTaskQueue,int netFd){
    task_t *newtask = (task_t *)calloc(1,sizeof(task_t));
    if(newtask == NULL){
        perror("calloc");
    }
    newtask->netFd = netFd;
    if(pTaskQueue->queuesize == 0){
        pTaskQueue->front = newtask;
        pTaskQueue->rear = newtask;
        pTaskQueue->queuesize++;
        return 0;
    }
    pTaskQueue->rear->next = newtask;
    pTaskQueue->rear = newtask;
    pTaskQueue->queuesize++;
    return 0;
}

int taskDequeue(taskQueue_t *pTaskQueue){
    task_t *deltask = pTaskQueue->front;
    pTaskQueue->front = deltask->next;
    if(pTaskQueue->front == NULL){
        pTaskQueue->rear = NULL;
    }
    int netFd = deltask->netFd;
    free(deltask);
    pTaskQueue->queuesize--;
    return netFd;
}


//线程池初始化
int threadPoolInit(threadPool_t *pthreadPool,int threadNum){
    pthreadPool->pidArr = (pthread_t *)calloc(threadNum,sizeof(pthread_t));
    if(pthreadPool->pidArr == NULL){
        perror("calloc");
        return -1;
    }
    bzero(&pthreadPool->taskQueue,sizeof(taskQueue_t));
    pthreadPool->threadNum = threadNum;
    pthreadPool->destory_flag = false;
    bzero(&pthreadPool->username,sizeof(pthreadPool->username));
    pthread_mutex_init(&pthreadPool->mutex,NULL);
    pthread_cond_init(&pthreadPool->cond,NULL);
}

//创建子线程并阻塞等待客户端连接
void makeWorker(threadPool_t *pthreadPool){
    for(int i=0;i<pthreadPool->threadNum;i++){
        pthread_create(&pthreadPool->pidArr[i],NULL,threadFunc,pthreadPool);
        printf("线程%ld创建成功\n",pthreadPool->pidArr[i]);
    }
}

void cleanFunc(void *pArgs){
    threadPool_t *pthreadPool = (threadPool_t *)pArgs;
    pthread_mutex_unlock(&pthreadPool->mutex);
 }

//线程任务函数指针
void *threadFunc(void* arg){
    threadPool_t *pthreadPool = (threadPool_t *)arg;
    if(pthreadPool == NULL){
        perror("pthreadPool");
        exit(-1);
    }
    int netFd;
    while(1){
        pthread_mutex_lock(&pthreadPool->mutex);
        //循环阻塞
        while(pthreadPool->taskQueue.queuesize == 0 && !pthreadPool->destory_flag){
            pthread_cond_wait(&pthreadPool->cond,&pthreadPool->mutex);
        }
        if(pthreadPool->destory_flag==1){
            pthread_mutex_unlock(&pthreadPool->mutex);
            printf("线程%ld退出\n",pthread_self());
            pthread_exit(NULL);
        }
        printf("线程%ld正在处理任务\n",pthread_self());
        netFd = taskDequeue(&pthreadPool->taskQueue);//从任务队列中接到网络套接字
        if(netFd == -1){
            perror("taskDequeue");
            pthread_mutex_unlock(&pthreadPool->mutex);
            continue;
        }
        pthread_mutex_unlock(&pthreadPool->mutex);
        Handlevent(netFd,pthreadPool);
        printf("task done!!!\n");
    }
}
//线程具体执行行为

void Handlevent(int sockFd,threadPool_t* threadpool){
    stack_int_t stack;
    init_stack(&stack);
    int key = -1;
    pthread_mutex_lock(&threadpool->mutex);
    MYSQL *pth_db = mysql_init(NULL);
    MYSQL *ret = mysql_real_connect(pth_db,"localhost","root","123456","CloudProject",0,NULL,0);
    pthread_mutex_unlock(&threadpool->mutex);
    printf("MYSQL connection success\n");
    if(ret == NULL){   
        printf("Error: %s\n", mysql_error(pth_db));
        return -1;
    }
    printf("username:%s\n",threadpool->username);
    //初始化主键
    db_init_thread(pth_db,threadpool->username,&key);
    //注册根目录
    printf("%d\n",key);
    if(key == -1){
        regfileroot(pth_db,threadpool->username,&key,&threadpool->mutex);
    }


    
    while(1){
        command cmd = {0};
        int ret = recv(sockFd,&cmd,sizeof(cmd),0);
        if(ret <= 0){
            printf("client disconnect\n");
            close(sockFd);
            return;
        }
        char result[BUF_SIZE] = {0};
        
        switch(cmd.type){
            case CMD_CD:
                task_cd(sockFd,&stack,pth_db);
                continue;
            case CMD_LS:
                task_ls(sockFd,&stack,pth_db);
                continue;
            case CMD_PUTS:
                task_puts();
                continue;
            case CMD_GETS:
                task_gets();
                continue;
            case CMD_RESUME_GETS:
                task_resume_gets();
                continue;
            case CMD_RESUME_PUTS:
                task_resume_puts();
                continue;
            case CMD_MKDIR:
                task_mkdir(sockFd,&stack,pth_db,&threadpool->mutex);
                continue;
            case CMD_RMDIR:
                task_rmdir(sockFd,&stack,pth_db,&threadpool->mutex);
                continue;
            case CMD_REMOVE:
                task_remove();
                continue;
            case CMD_PWD:
                task_pwd(sockFd,&stack,pth_db);
                continue;
            case CMD_QUIT:
                break;
            default:
                snprintf(result, sizeof(result), "Error: Unsupported or invalid command.\n");
                printf("result:%s\n",result);
                
                continue;
        }
    }
    printf("task finish\n");
    return NULL;
}
